package top.v5it.japi.plus.core;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import top.v5it.japi.plus.common.ConstantCommon;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;

/**
 * 常量池
 *
 * @author zhanpu
 * @date 20-11-25
 */
public interface ConstantPool extends ConstantCommon {

    String DASHED = StrUtil.DASHED;
    String DEFAULT_PREFIX_HEAD_JAPI = "Japi";
    String DEFAULT_PREFIX_KEY_JAPI = StrUtil.lowerFirst(DEFAULT_PREFIX_HEAD_JAPI);
    String POSTFIX_HASH_KEY_NONCE = "nonce_str";
    String POSTFIX_HEAD_SERIAL = "Serial";
    String POSTFIX_HEAD_NONCE = "Nonce";
    String POSTFIX_HEAD_TIMESTAMP = "Timestamp";
    String POSTFIX_HEAD_TOKEN = "Token";
    String POSTFIX_HEAD_SIGNATURE = "Signature";
    String POSTFIX_HEAD_CHANNEL = "Channel";
    String POSTFIX_HEAD_OPENID = "Openid";

    String NONCE_NAME = POSTFIX_HASH_KEY_NONCE;
    String TOKEN_NAME = StrUtil.lowerFirst(POSTFIX_HEAD_TOKEN);
    String TIMESTAMP_NAME = StrUtil.lowerFirst(POSTFIX_HEAD_TIMESTAMP);
    String SIGNATURE_NAME = StrUtil.lowerFirst(POSTFIX_HEAD_SIGNATURE);
    String SERIAL_NAME = "serial_no";

    String KEY_NAME = "key";
    String EMPTY = StrUtil.EMPTY;
    String AND = "&";
    String EQ = "=";
    String SEMICOLON = ";";
    String AND_KEY = AND + KEY_NAME + EQ;
    String COMMA = StrUtil.COMMA;
    String DELIM_START = StrUtil.DELIM_START;
    String BRACKET_START = StrUtil.BRACKET_START;
    String EQ_REGEX = "[\\" + EQ + "]";
    String AND_REGEX = "[\\" + AND + "]";
    char C_DELIM_START = StrUtil.C_DELIM_START;
    char C_BRACKET_START = StrUtil.C_BRACKET_START;
    String CHARACTER_ENCODING = "UTF-8";
    String CONTENT_TYPE_JSON = "application/json;charset=" + CHARACTER_ENCODING;
    String CONTENT_TYPE_FORM = "multipart/form-data";
    String CONTENT_TYPE = "Content-Type";
    String REDIS_SERVICE_NAME = "redisTemplate";
    String SPACE = StrUtil.SPACE;
    String AUTHORIZATION = "Authorization";
    String QUESTION = "?";
    String AUTHORIZATION_TYPE = "SHA256-RSA2048";
    String RESOURCE = "resource";
    String RESOURCE_TYPE = "resourceType";
    String CERT_END_TIME = "endTime";
    String JAPIEADA_NAME = "japiEada_79unlawful8yacht4sui9379hungover4567uj56xcv2wdf9iuh7yh2";
    String JAPIEADA_ALGORITHM_NAME = "japiEada_algorithm_9887rdv5438j72wec5678764eschew754eruption234t";
    String ALGORITHM = "RSA";

    /**
     * 获取义头信息前缀
     *
     * @return
     */
    static String getHeadPrefix() {
        return getJapi()
                .map(Japi::getHeadPrefix)
                .map(StrUtil::upperFirst)
                .orElse(DEFAULT_PREFIX_HEAD_JAPI);
    }

    /**
     * {@link Japi}
     *
     * @return
     */
    static Optional<Japi> getJapi() {
        try {
            return Optional.of(SpringUtil.getBean(Japi.class));
        } catch (Exception e) {
            return Optional.empty();
        }
    }

    /**
     * 快速失败
     *
     * @return
     */
    static boolean isFailFast() {
        return getJapi()
                .map(Japi::isFailFast)
                .orElse(Boolean.TRUE);
    }

    /**
     * 获取自定义异常类型
     *
     * @return
     */
    static Set<String> getExceptionSet() {
        return getJapi()
                .map(Japi::getExceptionSet)
                .orElseGet(Collections::emptySet);
    }

    /**
     * 获取授权类型
     *
     * @return 获取授权类型
     */
    static String getAuthorizationType() {
        String authorizationType = getJapi()
                .map(Japi::getAuthorizationType)
                .orElse(AUTHORIZATION_TYPE);

        return getHeadPrefix().toUpperCase() + DASHED + authorizationType;
    }

    /**
     * 加解密算法
     *
     * @return 加解密算法
     */
    static Japi.Eada getEada() {
        return getJapi()
                .map(Japi::getEada)
                .orElse(Japi.Eada.RSA);
    }

    /**
     * 获取自定义Serial头信息
     *
     * @return
     */
    static String getHeadSerialName() {
        return getHeadPrefix() + DASHED + POSTFIX_HEAD_SERIAL;
    }

    /**
     * 获取自定义Nonce头信息
     *
     * @return
     */
    static String getHeadNonceName() {
        return joinDashed(getHeadPrefix(), POSTFIX_HEAD_NONCE);
    }

    /**
     * 获取自定义Timestamp头信息
     *
     * @return
     */
    static String getHeadTimestampName() {
        return joinDashed(getHeadPrefix(), POSTFIX_HEAD_TIMESTAMP);
    }

    /**
     * 获取自定义Token头信息
     *
     * @return
     */
    static String getHeadTokenName() {
        return joinDashed(getHeadPrefix(), POSTFIX_HEAD_TOKEN);
    }

    /**
     * 获取自定义Signature头信息
     *
     * @return
     */
    static String getHeadSignatureName() {
        return joinDashed(getHeadPrefix(), POSTFIX_HEAD_SIGNATURE);
    }

    /**
     * 获取自定义Channel头信息
     *
     * @return
     */
    static String getHeadChannelName() {
        return joinDashed(getHeadPrefix(), POSTFIX_HEAD_CHANNEL);
    }

    /**
     * 获取自定义Openid头信息
     *
     * @return
     */
    static String getHeadOpenidName() {
        return joinDashed(getHeadPrefix(), POSTFIX_HEAD_OPENID);
    }

    /**
     * 获取缓存信息前缀
     *
     * @return 缓存数据key的前缀
     */
    static String getCachePrefix() {
        return getJapi()
                .map(Japi::getCachePrefix)
                .map(StrUtil::lowerFirst)
                .orElse(DEFAULT_PREFIX_KEY_JAPI);
    }

    /**
     * 获取channels缓存的key
     *
     * @return 接入渠道的缓存key
     */
    static String getCacheChannelKey() {
        return joinColon(getCachePrefix(), POSTFIX_HASH_KEY_CHANNEL);
    }

    /**
     * 加载客户端接入渠道时用到的分布式锁的缓存key
     *
     * @return
     */
    static String getCacheShardLockChannelKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SHARDLOCK_CHANNEL;
    }

    /**
     * 获取token缓存的key
     *
     * @return
     */
    static String getCacheTokenName() {
        return joinColon(getCachePrefix(), TOKEN_NAME);
    }

    /**
     * 获取nonce缓存的key前缀
     *
     * @return
     */
    static String getCacheNoncePrefixKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_NONCE + COLON;
    }

    /**
     * 将服务证书加载redis中的hash key
     *
     * @return
     */
    static String getCacheServerCertKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SERVER_CERT;
    }

    /**
     * 加载服务端证书时用到的分布式锁的缓存key
     *
     * @return
     */
    static String getCacheShardLockServerCertKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SHARDLOCK_CERT;
    }

    /**
     * 获取客户端证书缓存的key
     *
     * @return
     */
    static String getCacheClientCertKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_CLIENT_CERT;
    }

    /**
     * 加载客户端证书时用到的分布式锁的缓存key
     *
     * @return
     */
    static String getCacheShardLockClientCertKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SHARDLOCK_CLIENT_CERT;
    }

    /**
     * 获取客户端场所与接入渠道缓存的key
     *
     * @return
     */
    static String getCacheSiteChannelKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SITE_CHANNEL;
    }

    /**
     * 加载客户端场所与接入渠道时用到的分布式锁的缓存key
     *
     * @return
     */
    static String getCacheShardLockSiteChannelKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SHARDLOCK_SITE_CHANNEL;
    }

    /**
     * 获取客户端带密钥的接入渠道缓存的key
     *
     * @return
     */
    static String getCacheKeyChannelKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_KEY_CHANNEL;
    }

    /**
     * 加载客户端带密钥的接入渠道时用到的分布式锁的缓存key
     *
     * @return
     */
    static String getCacheShardLockKeyChannelKey() {
        return getCachePrefix() + COLON + POSTFIX_HASH_KEY_SHARDLOCK_KEY_CHANNEL;
    }

    /**
     * 按:分隔拼装字符
     *
     * @param params 待拼装的字符
     * @return 拼装后字符
     */
    static String joinColon(Object... params) {
        return StrUtil.join(COLON, params);
    }

    /**
     * 按-分隔拼装字符
     *
     * @param params 待拼装的字符
     * @return 拼装后字符
     */
    static String joinDashed(Object... params) {
        return StrUtil.join(DASHED, params);
    }

}
